#pragma once

#include <iostream>
#include <map>

#include "NxPhysics.h"

struct ColisoesRegistradas
{
	NxActor *objs[2];
	bool Colidiu;
};

class Colisoes : public NxUserContactReport
{
	public:
         void onContactNotify(NxContactPair& pair, NxU32 events)
         {
			 //percorre os registros de colisao
			 for(it = colidiu.begin(); it != colidiu.end(); it++)
				 //se esta ocorrendo um colisao entre objs que estao no registro
				 if( ((pair.actors[0] == it->second.objs[0]) && (pair.actors[1] == it->second.objs[1])) ||
					 ((pair.actors[0] == it->second.objs[1]) && (pair.actors[1] == it->second.objs[0]))    )
				 {
					 //se o tipo de colisao estao no registro
					 if(events == NX_NOTIFY_ON_TOUCH || events == NX_NOTIFY_ON_START_TOUCH)
							 it->second.Colidiu = true;
					 else if(events == NX_NOTIFY_ON_END_TOUCH)
							 it->second.Colidiu = false;
				 }
         }
	//guardas as colisoes adicionas identificadas por id
	std::multimap<int, ColisoesRegistradas> colidiu;
	std::multimap<int, ColisoesRegistradas>::iterator it;
};

class GerenciaFisica
{
public:
	GerenciaFisica(NxPhysicsSDK *PhysxSDK = NULL, NxScene *gscene = NULL, NxReal myTimestep = 0);
	~GerenciaFisica(void);

	void LoopFisica(void);
	bool run(void);

	void RegistraColisao(int idColisao, NxActor *obj1, NxActor *obj2);
	void TiraColisao(int idColisao);
	bool Colidiu(int idcolisao);
	bool ColidiuMulti(int idcolisao);

	void DesativaColisao(NxActor *obj1, NxActor *obj2);

	void DeleteActor(NxActor *obj);
	void DeleteColisoes();

	NxActor *CriaBoundingBox(NxVec3 posicao, NxVec3 dimensao, float massa, int material, bool dinamico = true);
	NxActor *CriaChao();

	void InverteGravidade();

	void drop();

private:

	NxPhysicsSDK *gPhysicsSDK;
	NxScene *gScene;
	NxReal myTimestep;
	Colisoes minhaColisao;
	bool gravNormal;
};

